using UnityEngine;
using System.Collections;

public class ShopBuyGui : MonoBehaviour, IClickableGui {
	/**
	 * Rectangle representing the current window appearance
	 */
	const int SHOP_NUM_ROWS = 5;
	const int SHOP_NUM_COLS = 2;
	const float SPACING=2;
	static bool DEBUG = true;
	
	private Rect WindowRect;
	public string title = "Shop";
	
	private int WindowID = 1;
	
	/* boxes representing shop's inventory */
	ItemContainerGui inv_boxes = null;
	
	/* TODO: figure out how to populate this safely */
	public ItemShop shop = null;
	
	GlobalAccess globals = null;
	PlayerPersistence player = null;
	
	bool destroy_self = false;
	
	Rect close_rect;
	
	PlayerPersistence GetPlayer() {
		if (this.player != null) {
			return this.player;
		}
		
		if (this.globals == null) {
			return null;
		}
		
		this.player = 
			(PlayerPersistence)this.globals.GetGlobalComponent(typeof(PlayerPersistence));
		
		return this.player;
	}
	
	void Awake () {
		float box_side = 48;
		float right_box_spacing = box_side * 1.5f;
		
		this.globals = new GlobalAccess();
		
		this.inv_boxes = new ItemContainerGui(new Vector2(0, 0),
			ShopBuyGui.SHOP_NUM_ROWS, ShopBuyGui.SHOP_NUM_COLS,
			box_side_length : box_side,
			left_box_spacing : 2,
			right_box_spacing : right_box_spacing);
	}
	
	void Start () {
		/* inventory is on top of cart, so only add heights */
		this.WindowRect = new Rect(30,30,
			this.inv_boxes.width,
			this.inv_boxes.height);
	}
	
	void OnGUI () {
		this.WindowRect = GUI.Window (this.WindowID, this.WindowRect, WindowFunc, this.title);
		if (this.destroy_self) {
			Destroy (this);
		}
	}
	
	int GetShopBuyableIndex(int row, int col) {
		return col + (row * this.inv_boxes.num_columns);
	}
	
	void WindowFunc(int id) {
		IEnumerator items;
		bool has_item;
		GuiImages images;
		
		if (this.destroy_self) {
			return;
		}
		
		if (this.globals == null) {
			return;
		}
		
		images = (GuiImages)this.globals.GetGlobalComponent(typeof(GuiImages));
		if (images == null) {
			return;
		}
		
		
		items = this.shop.GetBuyableEnumerator();
		/* have to move to first element */
		has_item = items.MoveNext();
		
		/**
		 * Draw shop inventory
		 * We kind of assume shop inventory does not change
		 * Also, we put the shop inventory in order
		 */
		for (int row=0; row<this.inv_boxes.num_rows; row++) {
			for (int col=0; col<this.inv_boxes.num_columns; col++) {
				Rect box = this.inv_boxes.GetBoxRect (row, col);
				
				GUI.Box (box, (string)null);
				if (has_item) {
					IShopBuyable b;
					Texture2D icon;
					
					b = (IShopBuyable)items.Current;
					
					GUI.Box(new Rect(
						box.xMin + this.inv_boxes.box_side_length,
						box.yMin,
						this.inv_boxes.right_box_spacing - ShopBuyGui.SPACING,
						this.inv_boxes.box_side_length),
						b.DisplayName () + "\n" +
							b.GetPrice().GetAmount(typeof(GoldCurrency)).ToString());
					
					icon = images.GetTexture(b.GetImagePath ());
					if (icon != null) {
						GUI.DrawTexture(box, icon);
					}
					
					has_item = items.MoveNext();
				}
			}
		}
		
		this.close_rect = new Rect(
			this.inv_boxes.width - this.inv_boxes.top_border, 0,
			this.inv_boxes.top_border, this.inv_boxes.top_border);
		GUI.Box (this.close_rect, "x");
		
		GuiIO.HandleMouseClick(this, Event.current);
		
	}
	
	protected void RightClickInventory(int row, int col) {
		ItemStack s;
		int amount;
		PlayerPersistence p;
						
		if (ShopBuyGui.DEBUG) {
			Debug.Log ("clicked row " + row.ToString () +
				" col " + col.ToString ());
		}
				
		amount = 1;
		s = this.shop.GetItemStackOfIndex(this.GetShopBuyableIndex(row, col), amount);
		if (s == null) {
			return;
		}
		
		if (ShopBuyGui.DEBUG) {
			Debug.Log ("clicked " + s.item.DisplayName ());
		}
		
		p = this.GetPlayer ();
		if (p == null) {
			return;
		}
		
		p.BuyItemStack(this.shop, s, s.item.GetPrice().Multiply(s.amount));
	}
	
	public void RightClick(Event e) {
		bool found;
		Pair<int, int> row_and_col = new Pair<int, int>(0, 0);
			
		found = this.inv_boxes.GetBoxFromPos (e.mousePosition, out row_and_col);
		
		switch (e.type) {
		case EventType.MouseDown:
			if (found) {
				this.RightClickInventory(row_and_col.Item1, row_and_col.Item2);
			}
			break;
		case EventType.MouseUp:
			break;
		default:
			/* should be unreachable */
			break;
		}
	}
	
	public void LeftClick(Event e) {
		if ((e.type == EventType.MouseUp) && (this.close_rect.Contains (e.mousePosition))) {
			this.destroy_self = true;
		}
	}
}
